#include "fbbackup.h"
#define RESPBUF	1024

FBBackup::FBBackup()
{
}
FBBackup::~FBBackup()
{
}

void FBBackup::set_config(QString db_file_,
                          QString out_file_,
                          QString user_,
                          QString pass_,
                          QString serv_name_,
                          bool verbose_)
{
db_file_ba = db_file_.toLatin1();
db_file = (char *) db_file_ba.data();

out_file_ba = out_file_.toLatin1();
out_file = (char *) out_file_ba.data();

user_ba = user_.toLatin1();
user = (char *) user_ba.data();

pass_ba = pass_.toLatin1();
pass = (char *) pass_ba.data();

serv_name_ba = serv_name_.toLatin1();
serv_name = (char *) serv_name_ba.data();

verbose = verbose_;
}

void FBBackup::run()
{

ISC_STATUS status[20];
isc_svc_handle svc_handle = 0L;
char svc_name[RESPBUF];
char spb_buff[RESPBUF];
char thd_buff[RESPBUF];
char sendbuf[] = {isc_info_svc_line};
char respbuf[RESPBUF];
char * p = respbuf;
char * spb = spb_buff;
char * thd = thd_buff;
char * x;
int spblen;
int thdlen;

/////////////////////////////
//
//  SPB
//

// Version
*spb++ = isc_spb_version;
*spb++ = isc_spb_current_version;

// User
*spb++ = isc_spb_user_name;
*spb++ = (char) strlen (user);
for (x = user; *x;)
{
*spb++ = *x++;
}
// Password
*spb++ = isc_spb_password;
*spb++ = (char) strlen(pass);
for (x = pass; *x;)
{
*spb++ = *x++;
}

//
//
////////////////////////////////////////

spblen = spb - spb_buff;

sprintf (svc_name, serv_name);

isc_service_attach (status,
                    0,
                    svc_name,
                    &svc_handle,
                    (unsigned short) spblen,
                    spb_buff);

    if ( (int) status[0] == 1 && status[1])
    {
    char err_buff[768];
    err_buff[0] = 'E';
    err_buff[1] = 'r';
    err_buff[2] = 'r';
    err_buff[3] = 'o';
    err_buff[4] = 'r';
    err_buff[5] = ':';
    err_buff[6] = ' ';
    ISC_STATUS * status_p = &status[0];
    isc_interprete (&err_buff[7], &status_p);
    emit log_line( QString(err_buff) + QString("\n") );
    return;
    }                    

////////////////////////////////////////
//
//  Service request block
//

// Action byte
*thd++ = isc_action_svc_backup;

//
// DB name
//
*thd++ = isc_spb_dbname;
// 2 bytes length of argument
int dbname_l = strlen(db_file);
int l1 = isc_vax_integer((char *) &dbname_l, 2);
char * d1 = (char *) &l1;
*thd++ = *d1++;
*thd++ = *d1++;
// Argument (database name)
    for (x = db_file; *x;)
    {
    *thd++ = *x++;
    }

//
// Backup file
//
*thd++ = isc_spb_bkp_file;
// 2 bytes length of argument
int back_l = strlen(out_file);
int l2 = isc_vax_integer((char *) &back_l, 2);
char * d2 = (char *) &l2;
*thd++ = *d2++;
*thd++ = *d2++;
// Argument (output file)
    for (x = out_file; *x;)
    {
    *thd++ = *x++;
    }

// "Verbose byte"
    if (true == verbose)
    {
    *thd++ = isc_spb_verbose;
    }
//
//
///////////////////////////////////////////////////////

thdlen = thd - thd_buff;

emit log_line(QString("Attach succeed\n"));

isc_service_start(status,
                  &svc_handle,
                  NULL,
                  (unsigned short) thdlen,
                  thd_buff);

    if ( (int) status[0] == 1 && status[1])
    {
    char err_buff[768];
    err_buff[0] = 'E';
    err_buff[1] = 'r';
    err_buff[2] = 'r';
    err_buff[3] = 'o';
    err_buff[4] = 'r';
    err_buff[5] = ':';
    err_buff[6] = ' ';
    ISC_STATUS * status_p = &status[0];
    isc_interprete (&err_buff[7], &status_p);
    emit log_line( QString(err_buff) + QString("\n") );

    isc_service_detach (status, &svc_handle);
    return;
    } 

emit log_line(QString("Backup is running ...\n"));
    
    do
    {
    QString output;
    isc_service_query (status,
                       &svc_handle,
                       NULL,
                       0,
                       NULL,
                       sizeof(sendbuf),
                       sendbuf,
                       RESPBUF,
                       respbuf);

        if ( (int) status[0] == 1 && status[1])
        {
        char err_buff[768];
        err_buff[0] = 'E';
        err_buff[1] = 'r';
        err_buff[2] = 'r';
        err_buff[3] = 'o';
        err_buff[4] = 'r';
        err_buff[5] = ':';
        err_buff[6] = ' ';
        ISC_STATUS * status_p = &status[0];
        isc_interprete (&err_buff[7], &status_p);
        emit log_line( QString(err_buff) + QString("\n") );
        
        isc_service_detach (status, &svc_handle);
        return;
        }

    x = p = respbuf;

        if (*p++ == isc_info_svc_line)
        {
        ISC_USHORT len = 0;
        ISC_USHORT i = 0;
        
        len = (ISC_USHORT)isc_vax_integer(p, sizeof(ISC_USHORT));
        p += sizeof (ISC_USHORT);

            if (!len)
            {
                if (*p ==  isc_info_data_not_ready)
                {
                output.append(QString("No data available now\n"));
                continue;
                }
                else
                {
                    if (*p != isc_info_end)
                    {
                    output.append( QString("Format error .. ") );
                    output.append( QString::number(*p) );
                    output.append( QString("\n") );
                    }
                break;
                }
            }

            for (i = 0; i < len; i++)
            {
            output.append( QString( p[i] ) );
            }
        
        p += len;

            if (*p != isc_info_truncated && *p != isc_info_end)
            {
            output.append( QString("Format error ... ") );
            output.append( QString::number(*p) );
            output.append( QString("\n") );
            break;
            }
        }
        else
        {
        output.append( QString("Not a isc_info_svc_line ") );
        output.append( QString::number(*x) );
        output.append( QString("\n") );
        }
    //emit log_line(output);
    } while (*x == isc_info_svc_line);
emit log_line(QString("Finished, detaching ...\n"));
isc_service_detach(status, &svc_handle);
}
